package com.tomica.mailsigner.fragment;

import java.util.Arrays;
import java.util.List;

import com.Wsdl2Code.WebServices.SignService.VectorString;
import com.entersafe.safeca.Constant;
import com.entersafe.safeca.MyProgressDialog;
import com.tomica.mailsigner.R;
import com.tomica.mailsigner.common.SettingsActivity;
import com.tomica.mailsigner.common.SettingsModel;
import com.tomica.mailsigner.fragment.PasswordDialogFragment.PasswordDialogListener;
import com.tomica.mailsigner.signmail.SignMailModel;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Base64;
import android.util.Log;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class SignMailFragment extends Fragment implements PasswordDialogListener{

	public static final int REQUEST_CODE = 1;

	private static final String TAG = "SingMailFragment";

	SignEmailListener mCallback;

	public TextView emailFrom;
	public EditText emailTo;
	public EditText emailCc;
	public EditText emailSubject;
	public EditText emailContent;
	public Button btnChangeSettings;
	public Button btnSend;

	private Context context;
	public Resources res;
	public MyProgressDialog progressDialog;

	private Handler handler;

	protected SignMailModel mModel;

	protected String pin;

	// The container Activity must implement this interface so the frag can deliver messages
	public interface SignEmailListener {
		/** Called by HeadlinesFragment when a list item is selected */
		public void onSignMail(VectorString addressFrom, VectorString addressCc, String subject, String content);
		public void onCallSettings();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// Inflate the layout for this fragment
		View rootView = inflater.inflate(R.layout.fragment_sign_mail, container, false);

		emailFrom = (TextView) rootView.findViewById(R.id.tvFromEmail);
		emailTo = (EditText) rootView.findViewById(R.id.etTo);
		emailCc = (EditText) rootView.findViewById(R.id.etCc);
		emailSubject = (EditText) rootView.findViewById(R.id.etSubject);
		emailContent = (EditText) rootView.findViewById(R.id.etMailContent);

		btnChangeSettings = (Button) rootView.findViewById(R.id.btnChangeSettings);
		btnChangeSettings.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// Account setting
				SignEmailListener activity = (SignEmailListener) getActivity();
				activity.onCallSettings();
			}
		});

		btnSend = (Button) rootView.findViewById(R.id.btnSignAndSend);
		btnSend.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// Validate data first

				String error = validate();
				if (error.length() != 0) {
					showErrorDialog(error);
				} else {
					showDialog();
				}
			}
		});
		return rootView;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		context = getActivity();
		res = getResources();


		progressDialog = new MyProgressDialog(context);

		handler = new Handler(){
			private String randomString;

			public void handleMessage(Message msg) {
				switch (msg.what) {
				case Constant.BUILD_MAIL_OK:
					// After build mail successful from web service, get the return
					// data to sign on token.

					// Call to sign PKCS11
					// Get data from server response:
					//result !=null se co 2 phan tu
					//result[0]: chua chuoi random dinh danh cho giao dich
					//result[1]: du lieu server tra ve dang base64,  client can ky len du lieu nay
					VectorString vectorResult = (VectorString) msg.obj;
					randomString = (String) vectorResult.getProperty(0);
					String serverDataBase64 = (String) vectorResult.getProperty(1);
					byte[] byteData  = Base64.decode(serverDataBase64, Base64.DEFAULT);
					mModel .signObjectVectorByte(byteData, pin);

					break;
				case Constant.GET_PASSWORD:
					progressDialog.setShowInfo(getResources().getString(R.string.inform_sign_onprogress));
					progressDialog.show();
					mModel.startSending(emailContent.getText().toString());

					break;
				case Constant.WRONG_PASSWORD:
					// Wrong password, user have to re-enter.
					showDialog();
					break;
				case Constant.MAIL_SIGNED_PKCS_OK:
					// After sign data successful on token, we are ready to send
					// mail by web service.
					VectorString toAddList = getEmailVector(emailTo.getText().toString());
					VectorString toCcList = getEmailVector(emailCc.getText().toString());
					String subject = emailSubject.getText().toString();
					mModel.sendMailEx((String) msg.obj, toAddList, toCcList,
							subject, pin, randomString);
					break;
				case Constant.SEND_MAIL_EX_OK:
					// Sending mail successful. Showing for user:
					progressDialog.dismiss();
					CharSequence text = context
							.getString(R.string.msg_send_successful);
					int duration = Toast.LENGTH_LONG;
					Toast toast = Toast.makeText(context, text, duration);
					toast.show();
					Log.d("Sendmai", "Complete");
					break;
				case Constant.SERVICE_EXCEPTION:
					// Error when interacting with web service. Display error message. 
					progressDialog.dismiss();
					String message = getResources().getString(R.string.inform_error_internal_server);
					showMessage(message);
					break;
				case Constant.BUILD_MAIL_FAIL:
					// Error when build mail with web service. Display error message. 
					progressDialog.dismiss();
					String buildMessage = getResources().getString(R.string.inform_error_internal_server);
					showMessage(buildMessage);
					break;
				case Constant.MAIL_SIGNED_PKCS_FAIL:
					// Error with token. Display error message.
					progressDialog.dismiss();
					String tokenErr = getResources().getString(R.string.inform_error_token);
					showMessage(tokenErr);
					break;
				case Constant.SEND_MAIL_EX_FAIL:
					// Error when send mail to web service. Display error message. 
					progressDialog.dismiss();
					String sendMessage = getResources().getString(R.string.inform_error_internal_server);
					showMessage(sendMessage);
					break;
				case Constant.SHOWPROGRESSDIALOG:
					Log.e(Constant.Debug, "Dialog of connecting token");
					progressDialog.setShowInfo(res.getString(R.string.inform_tryconnect_init));
					progressDialog.show();
					super.handleMessage(msg);
					break;
				case Constant.CLOSEPROGRESSDIALOG:
					progressDialog.dismiss();
					super.handleMessage(msg);
					break;
				case Constant.SHOWERRINFO:
					if (null != msg.obj) {
						if (msg.obj.toString().compareTo(
								res.getString(R.string.inform_handset_connectfail)) == 0) {
							String title, button;
							button = res.getString(R.string.inform_button_OK);
							title = res.getString(R.string.inform_title);
							new Builder(context)
							.setTitle(title)
							.setMessage(msg.obj.toString())
							.setPositiveButton(button,
									new DialogInterface.OnClickListener() {

								@Override
								public void onClick(
										DialogInterface arg0,
										int arg1) {
									// TODO
									//													finish();
								}
							}).show();
						} else
							showMessage(msg.obj.toString());
					}
					super.handleMessage(msg);
					break;
				case Constant.TOKEN_CONNECT_OK:
					// Show Toast inform that token connect successfully.
					CharSequence textOK = context.getString(R.string.inform_token_connect_ok);
					Toast toastOk = Toast.makeText(context, textOK, Toast.LENGTH_SHORT);
					toastOk.show();
					break;
				default:
					super.handleMessage(msg);
				}
			}
		};

		mModel = new SignMailModel(context, handler);
	}

	@Override
	public void onResume() {
		super.onResume();
		SettingsModel settings = new SettingsModel(context);
		emailFrom.setText(settings.getEmailAccount());
	}

	private void showErrorDialog(String error) {
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
		alertDialogBuilder.setMessage(error).setPositiveButton(
				this.getString(R.string.txt_ok),
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});
		AlertDialog alertDialog = alertDialogBuilder.create();
		alertDialog.show();
	}

	/**
	 * Validate user input. Error will return to string to display for user.
	 * @return
	 */
	public String validate() {

		// Validate Email To
		List<String> emailToList = getEmailList(emailTo.getText().toString());
		for (String email : emailToList) {
			if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
				return this.getString(R.string.txt_wrong_email_to) + ": "
						+ email;
			}
		}
		// Validate Email Cc
		List<String> emailCcList = getEmailList(emailCc.getText().toString());
		for (String email : emailCcList) {
			if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()
					&& email.length() != 0) {
				return this.getString(R.string.txt_wrong_email_cc) + ": "
						+ email;
			}
		}
		// Validate Subject
		String subject = emailSubject.getText().toString();
		if (subject.length() == 0) {
			return this.getString(R.string.txt_subjec_empty);
		}
		return "";
	}

	public List<String> getEmailList(String emailString) {
		return Arrays.asList(emailString.split("[,\\s]+"));
	}

	public VectorString getEmailVector(String emailString) {
		VectorString vector = new VectorString();
		if (emailString.length() != 0) {
			List<String> emailList = getEmailList(emailString);
			vector.setSize(emailList.size());
			for (int i = 0; i < emailList.size(); i++) {
				vector.set(i, emailList.get(i));
			}
		}
		return vector;
	}

	public boolean isOnline() {
		ConnectivityManager cm =
				(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = cm.getActiveNetworkInfo();
		if (netInfo != null && netInfo.isConnectedOrConnecting()) {
			return true;
		}
		return false;
	}

	/**
	 * Show dialog for user with content msg
	 * @param msg
	 */
	public void showMessage(String msg) {
		if (null == msg || "" == msg)
			return;
		String title, button;
		button = getResources().getString(R.string.inform_button_OK);
		title = getResources().getString(R.string.inform_title);
		new Builder(context).setTitle(title).setMessage(msg)
		.setPositiveButton(button, null).show();
	}

	@Override
	public void onFinishEditDialog(String password) {
		mModel.startSending(emailContent.getText().toString());
		Log.v(TAG, password);
	}
	private void showDialog() {
		PassDialogFragment newFragment = PassDialogFragment.newInstance();
		newFragment.setTargetFragment(this, REQUEST_CODE);
		newFragment.show(getFragmentManager().beginTransaction(), "dialog");
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch(requestCode) {
		case REQUEST_CODE:

			if (resultCode == Activity.RESULT_OK) {
				pin = data.getStringExtra("pass");
				Log.v(TAG, pin);
				progressDialog.setShowInfo(getResources().getString(R.string.inform_sign_onprogress));
				progressDialog.show();
				mModel.startSending(emailContent.getText().toString());

				// Show progressbar
			} else if (resultCode == Activity.RESULT_CANCELED){
				// After Cancel code.
			}
			break;
		}
	}
}
